home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-08-29 | 10.1 KB | 416 lines | [TEXT/KAHL] |
- /*
- DX Clock.c
- 13 août 1991
- Stephan Burlot 1991
-
- patches SystemTask to draw a clock in the menu bar.
-
- we use DrawString instead of multiple calls to DrawChars because some fonts are
- kerned and if we use DrawChar in srcCopy, it erases the right side of the previous
- char.
-
- this patch should be installed as a routine in JGNEFilter, so it would be
- easier to catch a click in the menu bar.
-
- */
-
- #include <color.h> /* some info about color quickdraw */
-
- #define RowBits 0x0C20 ; pixels horizontally
- #define WWExist 0x08F2 ; Window Manager Initialized ?
- #define WMgrCPort 0x0D2C ; [GLOBAL VAR] window manager color port
- #define WMgrPort 0x09DE ; Window Manager Port
- #define SystemTask 0xA9B4 ; System Task trap number
- #define GetNextEvent 0xA970 ; GetNextEvent trap number
- #define Unimplemented 0x9F ; Unimplemented trap number
- #define MBState 0x0172 ; Mouse Button state
- #define Mouse 0x0830 ; mouse loc
- #define FractEnable 0x0BF4 ; fractionnal width allowed ? (byte)
- #define MenuList 0x0A1C ; menu list
- #define MBTicks 0x016E ; tick count @ last mouse button [long]
- #define MenuCInfo 0x0D50 ; handle to Menu Color Info
- #define RGBBlack 0x0C10 ; RGB color black
- #define RGBWhite 0x0C16 ; RGB Color white
- #define ChunkyDepth 0x0D60 ; [GLOBAL VAR] depth of the pixels
-
- #define mctRGB1 0x4
- #define mctRGB4 0x16
-
- #define JMP 0x4EF9
-
- #define tnam 0
- #define pointer 4
- #define font 8
- #define size 10
- #define offset 12
- #define stringwid 14
- #define vpos 16
- #define red 18
- #define green 20
- #define blue 22
- #define therect 24
- #define toprect 24
- #define leftrect 26
- #define bottomrect 28
- #define rightrect 30
- #define useclockcolor 32
-
- pascal void ShowINIT() ;
-
- void Main(void) ;
-
- void main()
-
- {
- asm {
-
- move.l D4,-(SP) ; save some registers
-
- tst.b MBState ; mouse button down ?
- bpl @noPatch ; yes, dont install patch
-
- move.w #SystemTask,D0 ; get the address of the trap
- _GetTrapAddress ; result is in A0
-
- lea @exitST,A1
- move.l A0,(A1) ; save the address of trap into exitST
-
- lea @sysenvrec,A0 ; check the current system version
- move.w #1,D0
- _SysEnvirons
-
- lea @hascolor,A1 ; do we have color QD ?
- move.b 9(A0),(A1)
-
- move.w 4(A0),D0 ; system version is in D0
- cmp.w #0x700,D0 ; system seven ?
- bmi.s @system6 ; no
- move.w #65,D2 ; subtract width of two menus at top right corner
- bra.s @goon
- @system6
- move.w #20,D2 ; subtract width of on cue at top right corner
- @goon
-
- subq #4,SP ; space for handle
-
- move.l #'DXCL',-(SP) ; GetResource('DXCL',1)
- move.w #0x1,-(SP)
- _GetResource
-
- move.l (SP)+,A2 ; put handle to resource into A2
- move.l A2,D3 ; save a copy of the resource handle into D3
- movea.l (A2),A2 ; dereference handle.
-
- lea @last,A0 ; calculate size of patch
- lea @ThePatch,A1
- suba.l A1,A0
- move.l A0,D0
- move.l D0,D4 ; save D4 for BlockMove
- _NewPtr SYS ; allocate ptr in system heap /D0 used
- bne.s @noPatch ; if error, exit
-
- move.l A0,-(SP) ; save ptr onto heap
- move.w #SystemTask,D0
- _SetTrapAddress ; set the address of the new patch, A0/D0 used
-
- lea @ThePatch,A0
- move.l (SP),A1
- move.l D4,D0
- _BlockMove ; move the patch code into the system heap, A0/A1/D0 used
-
- lea @datarec,A0 ; calculate size of patch
- lea @ThePatch,A1
- suba.l A1,A0 ; offset of datarec from beginning of patch
- adda.l (SP)+,A0 ; add address of patch in sysheap. A0 contains the dest address
- move.l A0,A1 ; put A0 into A1 for BlockMove (A1 is dest address)
-
- move.l A0,pointer(A2) ; store ptr to data into the resource
- move.w D2,offset(A2) ; store offset into the resource
-
- move.l A2,A0
- move.l #34,D0 ; rec is 34 bytes long
- _BlockMove
-
- move.l D3,-(SP) ; save back the resource, because we've changed the pointer value
- _ChangedResource
- move.l D3,-(SP)
- _WriteResource
-
- @noPatch ; no patch, exit
-
- move.l (SP)+,D4
-
- ; move.w #128,-(SP)
- ; move.w #-1,-(SP)
- ; bsr ShowINIT
- rts
-
- @sysenvrec ; record filled by _SysEnvirons
- DC.W 0
- DC.W 0
- DC.W 0
- DC.W 0
- DC.B 0
- DC.B 0
- DC.W 0
- DC.W 0
- DC.W 0
-
- ;************************* the patch *********************************************/
-
- @ThePatch
-
- movem.l D0-D3/A0-A2,-(SP) ; save some registers
-
- tst.b WWExist ; Window Manager initialized ?
- bne @goodbye ; No : exit
- tst.w MBarHeight ; is there a menu bar ?
- beq @goodbye ; No : exit
-
- moveq #0,D3 ; D3:Boolean : draw the date ?
-
- move.w @leftrect,D0
-
- move.l MenuList,A1 ; we can draw the time if there is no menu on the clock's rect
- move.l (A1),A1
- move.w 2(A1),D1 ; 2(A1) holds the right coord of last menu
- cmp.w D0,D1 ; D0 holds the left coord of the clock's rect
- bgt @goodbye ; sorry, can't do that
-
- move.l #EventQueue,A0 ; test if there is a mouse down in the clock's rect
- move.l OFFSET(QHdr,qHead)(A0),A0
- beq.s @drawtime ; empty event queue ? yes, draw the time
-
- cmp.w #mouseDown,OFFSET(EvQEl,evtQWhat)(A0) ; is it a mouse down ?
- bne.s @drawtime ; no, continue
-
- subq #2,sp ; space for result
- move.l OFFSET(EvQEl,evtQWhere)(A0),-(SP) ; push the point
- pea @therect ; push the rect
- _PtInRect
- move.b (SP)+,D3
- bne.s @drawdate ; Pt is in rect, so draw the date
-
- @drawtime
-
- move.l @lasttime,D1 ; should we draw the time ?
- cmp.l Ticks,D1
- bgt @goodbye ; no, exit
-
- @drawdate
- pea @saveport ; saves the current port
- _GetPort
-
- ; _Debugger
- ; move.l @saveport,A0
- ; move.w OFFSET(GrafPort,portRect)(A0),D0
- ; move.w MBarHeight,D1
- ; cmp.w D0,D1
- ; ble @goodbye
-
- move.w @hascolor,D0 ; are we in color ?
- bne @initcolor
-
- move.l WMgrPort,-(SP) ; sets the port to the window manager port
- _SetPort
-
- move.l WMgrPort,A0 ; A0 holds a pointer to the window manager port
-
- move.w OFFSET(GrafPort,txFont)(A0),-(SP) ; save some params on the stack
- move.w OFFSET(GrafPort,txSize)(A0),-(SP)
- move.w OFFSET(GrafPort,txMode)(A0),-(SP)
- bra.s @endinit
-
- @initcolor
-
- move.l WMgrCPort,-(SP) ; sets the port to the color window manager port
- _SetPort
-
- move.l WMgrCPort,A0 ; A0 holds a pointer to the color window manager port
-
- move.w OFFSET(CGrafPort,txFont)(A0),-(SP) ; save some params on the stack
- move.w OFFSET(CGrafPort,txSize)(A0),-(SP)
- move.w OFFSET(CGrafPort,txMode)(A0),-(SP)
- lea @savedFGcolor,A1
-
- move.l OFFSET(CGrafPort,rgbFgColor)(A0),(A1)+ ; save the foreground color
- move.l OFFSET(CGrafPort,rgbFgColor+4)(A0),(A1)+
- move.l OFFSET(CGrafPort,rgbFgColor+8)(A0),(A1) ; save the background color
-
- /* the lines above were originally :
-
- move.l OFFSET(CGrafPort,rgbFgColor)(A0),(A1)+ ; save the foreground color
- move.w OFFSET(CGrafPort,rgbFgColor+4)(A0),(A1)+
- move.l OFFSET(CGrafPort,rgbBkColor)(A0),(A1)+ ; save the background color
- move.w OFFSET(CGrafPort,rgbBkColor+4)(A0),(A1)
-
- so we've saved 8 bytes !
- */
- move.l #RGBWhite,-(SP) ; push default colors on the stack
- move.l #RGBBlack,-(SP)
-
- move.w ChunkyDepth,D0 ; if we are in one bit mode,
- subq.w #1,D0
- beq.s @setcolor ; don't use MCInfo
-
- move.l MenuCInfo,A0
- move.l (A0),A0
- cmp.w #-99,(A0) ; item id is -99 if there is no MC entry
- beq.s @noMCentry
-
- lea mctRGB1(A0),A1 ; push foreground color
- move.l A1,(SP)
-
- lea mctRGB4(A0),A1 ; push background color
- move.l A1,4(SP)
-
- @noMCentry
- move.w @useclockcolor,D0 ; if we should use the clock's color
- beq.s @setcolor
- lea @thecolor,A1
- move.l A1,(SP)
- @setcolor
- _RGBForeColor ; set the foreground & background color
- _RGBBackColor
-
- @endinit
-
- pea @therect
- _ClipRect ; set the clipping region. (we dont save the old one)
-
- move.w @leftrect,-(SP)
- move.w @vpos,-(SP) ; v coord
- _MoveTo
-
- move.w @font,-(SP) ; set the font, size & mode
- _TextFont
- move.w @size,-(SP)
- _TextSize
- move.w #srcCopy,-(SP)
- _TextMode
-
- lea @DateTimeRec,A0 ; converts the date & time to num
- move.l Time,D0
- _Secs2Date
-
- lea @loop,A1 ; let's do some self modifying code !
- move.w #':',2(A1) ; use ':' to draw the time
- lea @a,A1
- move.w #0x3018,(A1) ; move.w (A0)+,D0
- tst.b D3
- beq.s @addoffset
-
- sub.w #1900,(A0) ; wont work in the 21th century !
- lea @loop,A1
- move.w #'.',2(A1) ; use '.' to draw the date
- lea @a,A1
- move.w #0x3020,(A1) ; move.w -(A0),D0
- @addoffset
- addq.w #6,A0 ; A0+6 points to the time
- lea @thestring,A1
- move.b #9,(A1)+ ; the string is 9 bytes long
-
- moveq #02,D2 ; loop 3 times
- bra.s @loop1 ; skip ':' at start
- @loop
- move.b #':',(A1)+ ; this line can be modified by the code above
- @loop1
- moveq #0,D0
- @a move.w (A0)+,D0
- divu.w #10,D0
- or.b #0x30,D0 ; ASCII('0') is 0x30
- move.b D0,(A1)+
- swap D0
- or.b #0x30,D0 ; ASCII('0') is 0x30
- move.b D0,(A1)+
- dbf D2,@loop
-
- pea @thestring
- _DrawString ; draw the string
-
- _TextMode ; restore things
- _TextSize
- _TextFont
- move.w @hascolor,D0
- beq.s @endrestore
-
- @restorecolor
-
- pea @savedFGcolor ; restore the foreground & background colors
- _RGBForeColor
- pea @savedBKcolor
- _RGBBackColor
-
- @endrestore
-
- move.l @saveport,-(SP) ; restore current port
- _SetPort
-
- lea @lasttime,A0 ; set the next time to 30 ticks ahead
- move.l Ticks,(A0)
- add.l #30,(A0)
- tst.b D3
- beq.s @goodbye
- add.l #180,(A0)
-
- @goodbye
-
- movem.l (SP)+,D0-D3/A0-A2 ; restore registers
- dc JMP
- @exitST ; here comes the address of the original patch
- nop
- nop
-
- @savedFGcolor DC.W 0 ; saved foreground color for CGrafPort
- DC.W 0
- DC.W 0
- @savedBKcolor DC.W 0 ; saved background color for CGrafPort
- DC.W 0
- DC.W 0
-
-
- @thestring DC.L 0 ; thestring holds the time. 10 bytes long.
- DC.L 0
- DC.W 0x0020 ; last char is always a space.
-
- @saveport DC.L 0 ; saved port
-
- @lasttime DC.L 0 ; last time we've drawn the clock
-
- @DateTimeRec ; holds the converted date & time
-
- @year DC.W 0
- @month DC.W 0
- @day DC.W 0
- @hour DC.W 0
- @minute DC.W 0
- @second DC.W 0
- @dayOfW DC.W 0
-
- @hascolor DC.W 0 ; has color QD ?
-
- @datarec ; we store the handle 'DXCL' here
-
- @tnam DC.L 0 ; identifier of the resource
- @pointer DC.L 0 ; loc of the ptr
- @font DC.W 0 ; font used
- @size DC.W 0 ; size of the font
- @offset DC.W 0 ; offset from left
- @stringwid DC.W 0 ; width of time
- @vpos DC.W 0 ; v coordinate
- @thecolor
- @red DC.W 0 ; red color
- @green DC.W 0 ; green color
- @blue DC.W 0 ; blue color
-
- @therect ; rect used for clipping
- @toprect DC.W 0
- @leftrect DC.W 0
- @bottomrect DC.W 0
- @rightrect DC.W 0
- @useclockcolor DC.W 0 ; use clock's color instead of menu bar's
-
- @last
- }
- }
-